#include "dominion.h"
#include <stdio.h>
#include "rngs.h"
#include <stdlib.h>
#include <math.h>
#include <string.h>

char* getCardString(int card) {
   char* kStrings[treasure_map + 1] = {   "curse", "estate", "duchy", 
                                          "province", "copper", "silver",
                                          "gold", "adventurer", "council_room",
                                          "feast", "gardens", "mine",
                                          "remodel", "smithy", "village",
                                          "baron", "great_hall", "minion",
                                          "steward", "tribute", "ambassador",
                                          "cutpurse", "embargo", "outpost",
                                          "salvager", "sea_hag", "treasure_map"
                                       };
   return kStrings[card];
}

void printGameState(struct gameState *G){
   int i;
   int j;
   printf("\n      ***Printing current gamestate***\n");
   for (i = 0; i < G->numPlayers; i++) {
      printf("     Player %d Hand: [", i+1);
      for (j = 0; j < G->handCount[i]; j++) {
         printf(" %s", getCardString(G->hand[i][j]));
      }
      printf("]\n");
      printf("              Deck: [");
      for (j = 0; j < G->deckCount[i]; j++) {
         printf(" %s", getCardString(G->deck[i][j]));
      }
      printf("]\n");
      printf("           Discard: [");
      for (j = 0; j < G->discardCount[i]; j++) {
         printf(" %s", getCardString(G->discard[i][j]));
      }
      printf("]\n");
   }
   printf("      ***End print***\n\n");  
}

int main (int argc, char** argv) {
   struct gameState G;
   int numberOfPlayers;
   int i, j;
   int k[10];
   int isDuplicate;
   int card;
   int currentPlayer;
   int seed;

   //Set verbosity level to control amount of detail in report
   int verbose = 0;
   int RNGS_stream;
   int RNGS_seed;
   if (argc == 4) {
      if (strncmp(argv[3], "--verbose", 9) == 0) {
         verbose = 1;
      }
      //Seed the random number generator
      RNGS_stream = atoi(argv[1]);
      RNGS_seed = atoi(argv[2]);
      SelectStream(RNGS_stream);
      PutSeed(RNGS_seed);
      //Create a random seed to start the game with
      seed = RNGS_seed + 13;
   }
   else if (argc == 3) {
      //Seed the random number generator
      RNGS_stream = atoi(argv[1]);
      RNGS_seed = atoi(argv[2]);
      SelectStream(RNGS_stream);
      PutSeed(RNGS_seed);
      //Create a random seed to start the game with
      seed = RNGS_seed + 13;
   }
   else {
      printf("USAGE ERROR: ./testdominion stream_integer seed_integer [--verbose]\n");
      return -1;
   }
   
   if (verbose) {
      printf("RNGS stream used = %d, RNGS seed used = %d, Gamestate seed = %d\n" , RNGS_stream, RNGS_seed, seed);
   }
   
   //Create 10 random numbers between 7 and 26 (ie adventurer and treasure_map)
   //   **They must be unique and stored in the array "k"
   for (i = 0; i < 10; i++) {
      isDuplicate = 1;
      while (isDuplicate) {
         card = adventurer + floor(Random() * (treasure_map - adventurer + 1));
         k[i] = card;
         isDuplicate = 0;
         //Check if card was a duplicate
         for (j = 0; j < i; j++) {
            if (k[j] == card) {
               isDuplicate = 1;
            }
         }
      }
   }
   
   //Create one random integer between 2-4
   numberOfPlayers = 2 + floor(Random() * 3);
   printf("Number of players: %d\n", numberOfPlayers);
   
   //Output the values of the cards in the current game
   printf ("Cards In Game: [ ");
   for (i = 0; i < 9; i++){
      printf ("%s, ", getCardString(k[i]));
   }
   printf ("%s ]\n", getCardString(k[9]));

   printf ("\nStarting game...\n");
   initializeGame(numberOfPlayers, k, seed, &G);
   if (verbose){
      printGameState(&G);
   }
   
   //Store available money for each turn
   int money;
   
   //Create an array to store the position of all kingdom cards
   // NOTE: duplicate cards will only be stored once!!
   int kingdomPos[treasure_map + 1];
   
   //Play Game!!
   while (!isGameOver(&G)) {
      //Reset all position values to -1
      for (i = 0; i < treasure_map + 1; i++)
         kingdomPos[i] = -1;
      
      //Initialize hand for current turn
      for (i = 0; i < numHandCards(&G); i++) {
         card = handCard(i, &G);
         if (card >= adventurer && card <= treasure_map)
            kingdomPos[card] = i;
      }
      //Set value for current player
      currentPlayer = whoseTurn(&G);
      //New round message:
      if (currentPlayer == 0) {
         printf("\nNew Round!!\n");
      }
      
      //Play a card 
      //(NOTE: if a valid card is not found in 900 tries, move on.
      card = -1;
      i = 0;
      while (card < 0 && i < 900) {
         j = adventurer + floor(Random() * (treasure_map - adventurer + 1));
         if (kingdomPos[j] != -1) {
            //Currently I only allow cards to be played that
            //do not require choices. I may update this in a later
            //version
            if ( j == adventurer ||
                 j == council_room ||
                 j == smithy ||
                 j == village ||
                 j == great_hall ||
                 j == tribute ||
                 j == cutpurse ||
                 j == outpost ||
                 j == sea_hag ||
                 j == treasure_map ) 
            {
                  playCard(kingdomPos[j], -1, -1, -1, &G);
                  card = j;
            }
         }
         i++;
      }
      if (card == -1)
         printf("   %d: No action taken...", currentPlayer);
      else
         printf("   %d: played %s...", currentPlayer, getCardString(card));

      //Set money value after action is done
      money = G.coins;
      int buy_test = 1;

      if (money >= 8) {
         buy_test = buyCard(province, &G);
         if (buy_test == 0) {
            printf(" bought province..."); 
         }
      }
      if (money >= 6) {
         //gold, adventurer cost 6
         i = floor(Random() * 2);
         if (i == 1 && G.supplyCount[adventurer] > 0) {
            buy_test = buyCard(adventurer, &G);
            if (buy_test == 0) {
               printf(" bought adventurer..."); 
            }
         }
         else {
            buy_test = buyCard(gold, &G);
            if (buy_test == 0) {
               printf(" bought gold..."); 
            }
         }   
      }
      if ( money == 5) {
         //duchy, council_room, mine, minion, tribute, outpost all cost 5
         i = floor(Random() * 6);
         if (i == 5 && G.supplyCount[duchy] > 0) {
            buy_test = buyCard(duchy, &G);
            if (buy_test == 0) {
               printf(" bought duchy..."); 
            }
         }
         else if (i == 4 && G.supplyCount[council_room] > 0) {
            buy_test = buyCard(council_room, &G);
            if (buy_test == 0) {
               printf(" bought council_room..."); 
            }
         }
         else if (i == 3 && G.supplyCount[mine] > 0) {
            buy_test = buyCard(mine, &G);
            if (buy_test == 0) {
               printf(" bought mine..."); 
            }
         }
         else if (i == 2 && G.supplyCount[minion] > 0) {
            buy_test = buyCard(minion, &G);
            if (buy_test == 0) {
               printf(" bought minion..."); 
            }
         }
         else if (i == 1 && G.supplyCount[tribute] > 0) {
            printf(" bought tribute..."); 
            buyCard(tribute, &G);
         }
         else if (i == 0 && G.supplyCount[outpost] > 0) {
            buy_test = buyCard(outpost, &G);
            if (buy_test == 0) {
               printf(" bought outpost..."); 
            }
         }
         else{
            //No default purchase at this level
         }
      }
      if ( money == 4) {
         //feast, gardens, remodel, smithy, baron, 
         //cutpurse, salvager, sea_hag, treasure_map all cost 4
         i = floor(Random() * 9);
         if (i == 8 && G.supplyCount[feast] > 0) {
            buy_test = buyCard(feast, &G);
            if (buy_test == 0) {
               printf(" bought feast..."); 
            }
         }
         else if (i == 7 && G.supplyCount[gardens] > 0) {
            buy_test = buyCard(gardens, &G);
            if (buy_test == 0) {
               printf(" bought gardens..."); 
            }
         }
         else if (i == 6 && G.supplyCount[remodel] > 0) {
            buy_test = buyCard(remodel, &G);
            if (buy_test == 0) {
               printf(" bought remodel..."); 
            }
         }
         else if (i == 5 && G.supplyCount[smithy] > 0) {
            buy_test = buyCard(smithy, &G);
            if (buy_test == 0) {
               printf(" bought smithy..."); 
            }
         }
         else if (i == 4 && G.supplyCount[baron] > 0) {
            buy_test = buyCard(baron, &G);
            if (buy_test == 0) {
               printf(" bought baron..."); 
            }
         }
         else if (i == 3 && G.supplyCount[cutpurse] > 0) {
            buy_test = buyCard(cutpurse, &G);
            if (buy_test == 0) {
               printf(" bought cutpurse..."); 
            }
         }
         else if (i == 2 && G.supplyCount[salvager] > 0) {
            buy_test = buyCard(salvager, &G);
            if (buy_test == 0) {
               printf(" bought salvager..."); 
            }
         }
         else if (i == 1 && G.supplyCount[sea_hag] > 0) {
            buy_test = buyCard(sea_hag, &G);
            if (buy_test == 0) {
               printf(" bought sea_hag..."); 
            }
         }
         else if (i == 0 && G.supplyCount[treasure_map] > 0) {
            buy_test = buyCard(treasure_map, &G);
            if (buy_test == 0) {
               printf(" bought treasure_map..."); 
            }
         }
         else{
            //No default purchase at this level
         }
      }
      if (money >= 3) {
         //silver, village, great_hall, steward, ambassador cost 3
         i = floor(Random() * 5);
         if (i == 4 && G.supplyCount[village] > 0) {
            buy_test = buyCard(village, &G);
            if (buy_test == 0) {
               printf(" bought village..."); 
            }
         }
         else if (i == 3 && G.supplyCount[great_hall] > 0) {
            buy_test = buyCard(great_hall, &G);
            if (buy_test == 0) {
               printf(" bought great_hall..."); 
            }
         }
         else if (i == 2 && G.supplyCount[steward] > 0) {
            buy_test = buyCard(steward, &G);
            if (buy_test == 0) {
               printf(" bought steward..."); 
            }
         }
         else if (i == 1 && G.supplyCount[ambassador] > 0) {
            buy_test = buyCard(ambassador, &G);
            if (buy_test == 0) {
               printf(" bought ambassador..."); 
            }
         }
         else {
            buy_test = buyCard(silver, &G);
            if (buy_test == 0) {
               printf(" bought silver..."); 
            }
         }         
      }
      if (money == 2) {
         //estate, embargo cost 2
         i = floor(Random() * 2);
         if (i == 1 && G.supplyCount[embargo] > 0) {
            buy_test = buyCard(embargo, &G);
            if (buy_test == 0) {
               printf(" bought embargo..."); 
            }
         }
         else if (i == 0 && G.supplyCount[estate] > 0) {
            buy_test = buyCard(estate, &G);
            if (buy_test == 0) {
               printf(" bought estate..."); 
            }
         }
         else{
            //No default purchase at this level 
         }
      }
      else {
         buy_test = buyCard(copper, &G);
         if (buy_test == 0) {
            printf(" bought copper...");
         }
      }
      
      printf("%d: end turn\n", currentPlayer);
      if (verbose){
         printGameState(&G);
      }
      endTurn(&G);
   } // end of While

   printf ("\nFinished game.\n");
   for (i = 0; i < numberOfPlayers; i++) 
      printf ("   Player %d: %d\n", i, scoreFor(i, &G));
   printf ("\n");
   return 0;
}